package com.yanqu.road.connect;

import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.net.operator.ConnectionOperator;

import java.util.ArrayList;
import java.util.List;

public abstract class ConnectionGroup<T extends Connection> extends Connection {

	private int connectionIndex = 0;

	protected Connection[] allConnections;

	public ConnectionGroup(int size) {
		super(true);
		init(size);
	}


	@Override
	public void write(YanQuMessage msg) {
		ConnectionOperator.connectionGroupWrite(allConnections, msg);
	}

	public void connectionSendMsg(YanQuMessage msg) {
		connectionIndex += ConnectionOperator.sendMsg(allConnections, msg, connectionIndex);
	}


	public void write(long userId, YanQuMessage msg) {
		msg.setPlayerId(userId);
		write(msg);
	}

	@Override
	public void flush() {

	}

	protected synchronized boolean init(int size) {
		close();
		allConnections = new Connection[size];
		return true;
	}

	public T get(int index) {
		int size = (allConnections != null) ? allConnections.length : 0;
		if (index < 0 || index >= size) {
			return null;
		}
		@SuppressWarnings("unchecked")
		T connection = (T) allConnections[index];
		if (!isConnectionAlive(connection)) {
			return null;
		}
		return connection;
	}


	@Override
	public void close() {
		int size = allConnections != null ? allConnections.length : 0;
		for (int i = 0; i < size; i++) {
			Connection connection = allConnections[i];
			if (connection != null) {
				connection.close();
			}
		}
		allConnections = null;
	}

	protected abstract T connect(int index) throws Exception;

	protected void writeToAll(YanQuMessage msg) {
		int size = (allConnections != null) ? allConnections.length : 0;
		for (int i = 0; i < size; i++) {
			@SuppressWarnings("unchecked")
			T connection = (T) allConnections[i];
			if (isConnectionAlive(connection)) {
				connection.write(msg);
			}
		}
	}

	public void keepAlive() {

	}



	public void addConnection(Connection connection, int index) {

	}

	public Connection[] getAllConnections() {
		return allConnections;
	}


	protected static boolean isConnectionAlive(Connection connection) {
		return ConnectionOperator.isConnectionAlive(connection);
	}

	public List<T> getAllConnectionList() {
		List<T> list = new ArrayList<>();
		if (allConnections == null || allConnections.length == 0) {
			return list;
		}
		int connectionSize = allConnections.length;
		for (int i = 0; i < connectionSize; i++) {
			@SuppressWarnings("unchecked")
			T connection = (T) allConnections[i];
			list.add(connection);
		}
		return list;
	}


}
